package com.zhiwen.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhiwen.common.exception.BusinessException;
import com.zhiwen.domain.dto.CollectionDTO;
import com.zhiwen.domain.entity.Answer;
import com.zhiwen.domain.entity.Question;
import com.zhiwen.domain.entity.UserCollection;
import com.zhiwen.mapper.QuestionMapper;
import com.zhiwen.mapper.UserCollectionMapper;
import com.zhiwen.service.AnswerService;
import com.zhiwen.service.QuestionService;
import com.zhiwen.service.UserCollectionService;
import com.zhiwen.domain.vo.QuestionVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户收藏服务实现类
 */
@Service
@RequiredArgsConstructor
public class UserCollectionServiceImpl extends ServiceImpl<UserCollectionMapper, UserCollection> implements UserCollectionService {

    private final QuestionService questionService;
    private final QuestionMapper questionMapper;
    private final AnswerService answerService;

    /**
     * 添加收藏
     *
     * @param collectionDTO 收藏信息
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addCollection(CollectionDTO collectionDTO) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 检查是否已收藏
        if (checkCollected(collectionDTO)) {
            return true;
        }

        // 检查目标对象是否存在
        checkTargetExists(collectionDTO);

        // 创建收藏记录
        UserCollection collection = new UserCollection();
        collection.setUserId(userId);
        collection.setTargetId(collectionDTO.getTargetId());
        collection.setType(collectionDTO.getType());
        collection.setCreateTime(LocalDateTime.now());
        collection.setUpdateTime(LocalDateTime.now());
        collection.setDeleted(0);

        // 保存收藏记录
        return this.save(collection);
    }

    /**
     * 取消收藏
     *
     * @param collectionDTO 收藏信息
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean cancelCollection(CollectionDTO collectionDTO) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getUserId, userId)
                .eq(UserCollection::getTargetId, collectionDTO.getTargetId())
                .eq(UserCollection::getType, collectionDTO.getType())
                .eq(UserCollection::getDeleted, 0);

        UserCollection collection = this.getOne(wrapper);

        if (collection == null) {
            return false;
        }

        // 逻辑删除收藏记录
        collection.setDeleted(1);
        collection.setUpdateTime(LocalDateTime.now());

        return this.updateById(collection);
    }

    /**
     * 检查是否收藏
     *
     * @param collectionDTO 收藏信息
     * @return 是否已收藏
     */
    @Override
    public boolean checkCollected(CollectionDTO collectionDTO) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getUserId, userId)
                .eq(UserCollection::getTargetId, collectionDTO.getTargetId())
                .eq(UserCollection::getType, collectionDTO.getType())
                .eq(UserCollection::getDeleted, 0);

        return this.count(wrapper) > 0;
    }

    /**
     * 检查目标对象是否存在
     *
     * @param collectionDTO 收藏信息
     */
    private void checkTargetExists(CollectionDTO collectionDTO) {
        Integer type = collectionDTO.getType();
        Long targetId = collectionDTO.getTargetId();

        if (type == 1) {
            // 问题
            Question question = questionService.getById(targetId);
            if (question == null) {
                throw new BusinessException("问题不存在");
            }
        } else if (type == 2) {
            // 回答
            Answer answer = answerService.getById(targetId);
            if (answer == null) {
                throw new BusinessException("回答不存在");
            }
        } else {
            throw new BusinessException("无效的收藏类型");
        }
    }

    /**
     * 收藏问题
     *
     * @param userId     用户ID
     * @param questionId 问题ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void collectQuestion(Long userId, Long questionId) {
        // 检查是否已收藏
        if (checkCollected(userId, questionId)) {
            return;
        }

        // 检查问题是否存在
        Question question = questionMapper.selectById(questionId);
        if (question == null) {
            throw new RuntimeException("问题不存在");
        }

        // 创建收藏记录
        UserCollection collection = new UserCollection();
        collection.setUserId(userId);
        collection.setTargetId(questionId);
        collection.setType(1); // 1表示问题

        // 保存收藏记录
        this.save(collection);
    }

    /**
     * 取消收藏
     *
     * @param userId     用户ID
     * @param questionId 问题ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancelCollect(Long userId, Long questionId) {
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getUserId, userId)
                .eq(UserCollection::getTargetId, questionId)
                .eq(UserCollection::getType, 1);

        this.remove(wrapper);
    }

    /**
     * 检查是否已收藏
     *
     * @param userId     用户ID
     * @param questionId 问题ID
     * @return 是否已收藏
     */
    public boolean checkCollected(Long userId, Long questionId) {
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getUserId, userId)
                .eq(UserCollection::getTargetId, questionId)
                .eq(UserCollection::getType, 1);

        return this.count(wrapper) > 0;
    }

    /**
     * 获取用户收藏的问题列表
     *
     * @param userId  用户ID
     * @param current 当前页
     * @param size    每页数量
     * @return 问题分页对象
     */
    @Override
    public Page<QuestionVO> getCollectedQuestions(Long userId, Integer current, Integer size) {
        // 查询用户收藏的问题ID列表
        LambdaQueryWrapper<UserCollection> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCollection::getUserId, userId)
                .eq(UserCollection::getType, 1)
                .orderByDesc(UserCollection::getCreateTime);

        Page<UserCollection> collectionPage = new Page<>(current, size);
        this.page(collectionPage, wrapper);

        // 如果没有收藏记录，返回空页面
        if (collectionPage.getRecords().isEmpty()) {
            return new Page<>(current, size);
        }

        // 获取问题ID列表
        List<Long> questionIds = collectionPage.getRecords().stream()
                .map(UserCollection::getTargetId)
                .collect(Collectors.toList());

        // 查询问题详情
        List<QuestionVO> questionVOList = new ArrayList<>();
        for (Long questionId : questionIds) {
            QuestionVO questionVO = questionService.getQuestionDetail(questionId);
            if (questionVO != null) {
                questionVOList.add(questionVO);
            }
        }

        // 构建返回结果
        Page<QuestionVO> questionPage = new Page<>(current, size, collectionPage.getTotal());
        questionPage.setRecords(questionVOList);

        return questionPage;
    }
}
